//
//  JSWebWKWebViewAdapter.m
//  JSWebDemo
//
//  Created by ac-hu on 2018/7/7.
//  Copyright © 2018年 ac-hu. All rights reserved.
//

#import "JSWebWKWebViewAdapter.h"
#import <objc/runtime.h>
#import "JSWebControllerManager.h"
#import "NSString+JSWeb.h"
#import "JSWebCallbackManager.h"


static void *WkwebBrowserContext = &WkwebBrowserContext;

@interface JSWebWKWebViewAdapter()<WKUIDelegate,WKNavigationDelegate,UIScrollViewDelegate>
{
    CGFloat _scrollY;
}
@property(nonatomic,strong)WKWebView *wkWebView;
@property(nonatomic,strong)UIView *progressView;
@property(nonatomic,strong)UIActivityIndicatorView *activityIndicatorView;
@property(nonatomic,strong)UIView *noDataView;
@property(nonatomic,assign)float progressBeginY;

//返回按钮
@property (nonatomic) UIBarButtonItem* customBackBarItem;
//关闭按钮
@property (nonatomic) UIBarButtonItem* closeButtonItem;
@end

@implementation JSWebWKWebViewAdapter
-(instancetype)initWithWKWebView:(WKWebView *)wkWebView{
    if (self = [super init]) {
        self.wkWebView = wkWebView;
        self.wkWebView.UIDelegate = self;
        self.wkWebView.navigationDelegate = self;
        self.wkWebView.scrollView.delegate = self;
        [self creatUI];
        [self.wkWebView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:0 context:WkwebBrowserContext];
        [_wkWebView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil];
        [_wkWebView addObserver:self forKeyPath:@"URL" options:NSKeyValueObservingOptionNew context:nil];
    }
    return self;
}

-(void)creatUI{
    self.noDataView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.wkWebView.frame.size.width, self.wkWebView.frame.size.height)];
    self.noDataView.backgroundColor = self.wkWebView.backgroundColor;
    [self.wkWebView addSubview:self.noDataView];
    
    UILabel *noDataLabel = [[UILabel alloc]init];
    noDataLabel.textColor = [UIColor darkTextColor];
    noDataLabel.text = @"当前网络断开。请连接后刷新";
    noDataLabel.font = [UIFont systemFontOfSize:14.f];
    NSMutableAttributedString *AttributedStr = [[NSMutableAttributedString alloc]initWithString:noDataLabel.text];
    NSRange labelRang = [noDataLabel.text rangeOfString:@"刷新"];
    [AttributedStr addAttribute:NSFontAttributeName
                          value:[UIFont boldSystemFontOfSize:16]
                          range:labelRang];
    [AttributedStr addAttribute:NSForegroundColorAttributeName
                          value:[UIColor blueColor]
                          range:labelRang];
    noDataLabel.attributedText = AttributedStr;
    [self.noDataView addSubview:noDataLabel];
    
    UITapGestureRecognizer *noDataLabelTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(reloadUrl)];
    self.noDataView.userInteractionEnabled = YES;
    noDataLabel.userInteractionEnabled = YES;
    [noDataLabel addGestureRecognizer:noDataLabelTap];
    [noDataLabel sizeToFit];
    noDataLabel.center = CGPointMake(self.noDataView.frame.size.width/2.f, self.noDataView.frame.size.height/2.f);
    self.noDataView.backgroundColor = [UIColor whiteColor];
    self.noDataView.hidden = YES;
    
    self.progressHeight = 4.f;
    self.progressView = [[UIView alloc]initWithFrame:CGRectMake(0, _progressBeginY, 0, _progressHeight)];
    self.progressView.backgroundColor = [UIColor redColor];
    self.progressView.hidden = YES;
    [self.wkWebView addSubview:self.progressView];
    
    self.activityIndicatorView = [[UIActivityIndicatorView alloc]init];
    self.activityIndicatorView.center = CGPointMake(self.wkWebView.frame.size.width/2.f, self.wkWebView.frame.size.height / 2.f);
    self.activityIndicatorView.bounds = CGRectMake(0, 0, 80, 80);
    self.activityIndicatorView.hidden = YES;
    self.activityIndicatorView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
    [self.wkWebView addSubview:self.activityIndicatorView];
}

-(void)setProgressHeight:(float)progressViewHeight{
    _progressHeight = progressViewHeight;
    self.progressView.frame = CGRectMake(0, _progressBeginY, self.wkWebView.frame.size.width, progressViewHeight);
}

-(void)setProgressColor:(UIColor *)progressColor{
    _progressColor = progressColor;
    self.progressView.tintColor = progressColor;
}

#pragma mark ================ 自己方法 ================

-(void)startLoad{
    [self.wkWebView bringSubviewToFront:self.activityIndicatorView];
    [self.wkWebView bringSubviewToFront:self.progressView];
    self.progressView.hidden = NO;
    self.activityIndicatorView.hidden = NO;
    _progressBeginY = self.viewController.navHidden ? 0 : self.viewController.navigationController.navigationBar.frame.size.height;
    self.progressView.frame = CGRectMake(0, _progressBeginY, 0, _progressHeight);
    [self.activityIndicatorView startAnimating];
}

-(void)endLoad{
    self.progressView.hidden = YES;
    self.activityIndicatorView.hidden = YES;
    self.progressView.frame = CGRectMake(0, 0, 0, _progressHeight);
    [self.activityIndicatorView stopAnimating];
}

-(void)showNoDataView{
    [self.wkWebView bringSubviewToFront:self.noDataView];
    self.noDataView.hidden = NO;
}

-(void)hiddenNoDataView{
    self.noDataView.hidden = YES;
}

-(void)reloadUrl{
    [self loadUrl];
    [self hiddenNoDataView];
}

-(void)loadUrl{
    if ([self.urlStr containsString:@"http"]) {
        NSURL *url = [NSURL URLWithString:self.urlStr];
//        NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:0 timeoutInterval:10.f];
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.f];
//////                设置请求头
////                [request setValue:@"11111" forHTTPHeaderField:@"seesion"];
//////                设置请求体
////                [requestShare setHTTPMethod: @"POST"];
////                [request setHTTPBody:data];
        [request setValue:[NSString stringWithFormat:@"PHPSESSID=6qg6vfrqs7sjm4h7oii993r1e4"] forHTTPHeaderField:@"Cookie"];
        for (NSDictionary *dic in request.allHTTPHeaderFields) {
            NSLog(@"%@",dic);
        }
        [self.wkWebView loadRequest:request];
        return;
    }
    //获取JS所在的路径
    NSString *path = [[NSBundle mainBundle] pathForResource:self.urlStr ofType:@"html"];
    //获得html内容
    NSString *html = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    //加载js
    [self.wkWebView loadHTMLString:html baseURL:[[NSBundle mainBundle] bundleURL]];
}

-(void)getResponseHeader{
    NSString *doc = @"document.head.outerHTML";
    [self.wkWebView evaluateJavaScript:doc completionHandler:^(id _Nullable htmlStr, NSError * _Nullable error) {
        if (error) {
            NSLog(@"JSError:%@",error);
        }
        NSLog(@"html:%@",htmlStr);
    }] ;
}

-(void)getResponseBody{
    NSString *doc = @"document.body.outerHTML";
    [self.wkWebView evaluateJavaScript:doc completionHandler:^(id _Nullable htmlStr, NSError * _Nullable error) {
        if (error) {
            NSLog(@"JSError:%@",error);
        }
        NSLog(@"html:%@",htmlStr);
    }] ;
}

-(void)getUserAgent{
    [self.wkWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) {
        NSString *resultStr = nil;
        if (error) {
            resultStr = error.description;
        }else{
            resultStr = result;
        }
        NSLog(@"userAgent = %@",resultStr);
    }];
}

#pragma mark ================ WKNavigationDelegate ================

//开始加载
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    //    //开始加载的时候，让加载进度条显示
    [self startLoad];
    
}

//内容返回时调用
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    
}

//接受到服务器请求跳转的时候调用
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
    
}

// 在收到响应后，决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    
    //    NSLog(@"这是网址%@的响应",navigationResponse.response.URL.absoluteString);
    //允许跳转
    decisionHandler(WKNavigationResponsePolicyAllow);
}

//发送请求前，决定是否跳转，可拦截URL
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {}
    else if (navigationAction.navigationType == WKNavigationTypeFormSubmitted) {}
    else if (navigationAction.navigationType == WKNavigationTypeBackForward) {
        //        NSLog(@"gobackAction");
    }else if (navigationAction.navigationType == WKNavigationTypeReload) {}
    else if (navigationAction.navigationType == WKNavigationTypeFormResubmitted) {}
    else if (navigationAction.navigationType == WKNavigationTypeOther) {}
    decisionHandler(WKNavigationActionPolicyAllow);
}
/// 5 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    
    //    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //        dispatch_async(dispatch_get_main_queue(), ^{
    //            [self endLoad];
    //        });
    //    });
    //
    //    [SVProgressHUD dismiss];
    //    DeLog(@"完成%lu",(unsigned long)self.hash);
    //
    //    //通知WebActionManager已加载完成
    //    [[WebActionManager shareInstance]didfinishLoadUrl:self.URLString];
    //    // 获取加载网页的标题
    //    if (!self.wkWebView.title.length) {
    //        self.viewController.title = self.wkWebView.title;
    //    }
    //
    //    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    //
    //
    [self hiddenNoDataView];
    [self updateNavigationItems];
}



// 内容加载失败时候调用
-(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{
    NSLog(@"页面加载超时%lu",(unsigned long)self.hash);
    [self endLoad];
    [self showNoDataView];
}

//跳转失败的时候调用
-(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    
}

//9.0才能使用，web内容处理中断时会触发
-(void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
    //    [webView reload];
}

#pragma mark ================ WKUIDelegate ================

// 获取js 里面的提示
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    if ([message isEqualToString:@"保存用户信息成功"]) {
        NSLog(@"这里跨界面，请采用通知刷新用户信息");
    }
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }]];
    
    [self.viewController presentViewController:alert animated:YES completion:NULL];
    
}

// js 信息的交流
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }]];
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }]];
    [self.viewController presentViewController:alert animated:YES completion:NULL];
}

// 交互。可输入的文本。
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.textColor = [UIColor redColor];
    }];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler([[alert.textFields lastObject] text]);
    }]];
    
    [self.viewController presentViewController:alert animated:YES completion:NULL];
    
}

#pragma mark ================ UIScrollViewDelegate ================
//-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
//    
//    UIView *view = self.viewController.navigationController.navigationBar;
//    if (view.frame.size.height > 0) {
//        if (_scrollY < scrollView.contentOffset.y){
//            NSLog(@"%f",scrollView.contentOffset.y - _scrollY);
//            view.frame = CGRectMake(VIEW_XMIN(view), VIEW_YMIN(view), VIEW_W(view), VIEW_H(view) - (scrollView.contentOffset.y - _scrollY) /2.f);
//            view. = CGRectEdge(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>)
//            [self.viewController viewDidLayoutSubviews];
//
//        }
//    }
//    
//    _scrollY = scrollView.contentOffset.y;
//}
#pragma mark ================ KVO ================
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.wkWebView) {
        [self.progressView setAlpha:1.0f];
        __weak typeof(self) weekSelf = self;
        if ((weekSelf.progressView.frame.size.width / weekSelf.wkWebView.frame.size.width) > self.wkWebView.estimatedProgress) {
            return;
        }
        [UIView animateWithDuration:0.1 animations:^{
            weekSelf.progressView.frame = CGRectMake(0, weekSelf.progressBeginY, weekSelf.wkWebView.estimatedProgress * weekSelf.wkWebView.frame.size.width, weekSelf.progressHeight);
        } completion:^(BOOL finished) {
            if(weekSelf.wkWebView.estimatedProgress >= 1.0f) {
                [UIView animateWithDuration:0.3f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
                    [weekSelf.progressView setAlpha:0.0f];
                } completion:^(BOOL finished) {
                    weekSelf.progressView.alpha = 1.;
                    [weekSelf endLoad];
                }];
            }
        }];
    }else if([keyPath isEqualToString:NSStringFromSelector(@selector(title))] && object == self.wkWebView) {
        [self updateNavigationItems];
    }else if([keyPath isEqualToString:NSStringFromSelector(@selector(URL))] && object == self.wkWebView) {
        [self updateNavigationItems];
    }
}

#pragma mark - 处理解决-[WKContentView isSecureTextEntry]: unrecognized selector sent to instance 异常
+ (void)load {
    
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        
        if ([[UIDevice currentDevice].systemVersion floatValue]< 8.0) {
            return;
        }
        
        Class WKContentViewCls = objc_getClass("WKContentView");
        
        if (!WKContentViewCls) { return;}
        
        SEL isSecureTextEntrySel = @selector(isSecureTextEntry);
        
        if (![WKContentViewCls instancesRespondToSelector:isSecureTextEntrySel]) {
            
            BOOL isSecureTextEntryAdded = class_addMethod(WKContentViewCls, isSecureTextEntrySel, class_getMethodImplementation(self, isSecureTextEntrySel), "B@:");
            
            if (!isSecureTextEntryAdded) {
                NSLog(@"isSecureTextEntry 添加失败");
            }
            
        }
        
        SEL secureTextEntrySel = @selector(secureTextEntry);
        
        if (![WKContentViewCls instancesRespondToSelector:secureTextEntrySel]) {
            
            BOOL secureTextEntryAdded = class_addMethod(WKContentViewCls, secureTextEntrySel, class_getMethodImplementation(self, secureTextEntrySel), "B@:");
            
            if (!secureTextEntryAdded) {
                
                NSLog(@"isSecureTextEntry 添加失败");
            }
        }
    });
}

- (BOOL)isSecureTextEntry {
    return NO;
}

- (BOOL)secureTextEntry  {
    return NO;
}

-(void)removeConfig{
    [self.wkWebView setNavigationDelegate:nil];
    [self.wkWebView setUIDelegate:nil];
    self.wkWebView.scrollView.delegate = nil;
    [self.wkWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
    [self.wkWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(URL))];
    [self.wkWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(title))];
    [self cleanCacheAndCookie];
}
//清除缓存
- (void)cleanCacheAndCookie
{
    NSHTTPCookie *cookie;
    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (cookie in [storage cookies]){
        [storage deleteCookie:cookie];
    }
    
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    NSURLCache * cache = [NSURLCache sharedURLCache];
    [cache removeAllCachedResponses];
    [cache setDiskCapacity:0];
    [cache setMemoryCapacity:0];
    
    if (@available(iOS 9.0, *)) {
        WKWebsiteDataStore *dateStore = [WKWebsiteDataStore defaultDataStore];
        [dateStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes]
                         completionHandler:^(NSArray<WKWebsiteDataRecord *> * __nonnull records){
                             for (WKWebsiteDataRecord *record  in records){
                                 [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:record.dataTypes
                                                                           forDataRecords:@[record]
                                                                        completionHandler:^{
                                                                            NSLog(@"Cookies for %@ deleted successfully",record.displayName);
                                                                        }];
                             }
                         }];
    } else {
        // Fallback on earlier versions
    }
}

#pragma mark ================ NAVUI ================
-(void)updateNavigationItems{
    self.viewController.title = self.wkWebView.title;
    if (self.wkWebView.canGoBack) {
        UIBarButtonItem *spaceButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
        spaceButtonItem.width = -6.5;
        
        [self.viewController.navigationItem setLeftBarButtonItems:@[spaceButtonItem,self.customBackBarItem] animated:NO];//,self.closeButtonItem
    }else{ self.viewController.navigationController.interactivePopGestureRecognizer.enabled = YES;
        [self.viewController.navigationItem setLeftBarButtonItems:@[]];
    }
}

-(UIBarButtonItem*)customBackBarItem{
    if (!_customBackBarItem) {
        _customBackBarItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(customBackItemClicked)];
    }
    return _customBackBarItem;
}

-(UIBarButtonItem*)closeButtonItem{
    if (!_closeButtonItem) {
        _closeButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(closeItemClicked)];
    }
    return _closeButtonItem;
}

-(void)customBackItemClicked{
    if (self.wkWebView.canGoBack) {
        [self.wkWebView goBack];
    }else{
        [JSWebControllerManager popViewController];
    }
}
-(void)closeItemClicked{
    //    这里根据需求来返回界面
    //    [JSWebControllerManager popViewController];
    [JSWebControllerManager popToRootViewController];
}

-(BOOL)isEmptyStr:(NSString *)str
{
    if(nil == str)
    {
        return YES;
    }
    if([str isKindOfClass:[NSNull class]])
    {
        return YES;
    }
    if(0 == str.length)
    {
        return YES;
    }
    return NO;
}

-(void)dealloc{
    NSLog(@"Adapter被销毁");
}

@end


